﻿#include<jni.h>
#include "memory.h"


extern "C" {

	// 设置安全写入启用状态
	JNIEXPORT void JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_setIsSecureWrites(JNIEnv* env, jclass clazz, jboolean sw) {
		setIsSecureWrites(sw);
	}


	// 获取模块起始地址(基址)
	JNIEXPORT jlong JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getModuleBaseAddr(JNIEnv* env, jclass clazz, jstring moduleName, jint headType) {
		const char* nativeModuleName = env->GetStringUTFChars(moduleName, nullptr);
		unsigned long result = getModuleBaseAddr(nativeModuleName, headType);
		env->ReleaseStringUTFChars(moduleName, nativeModuleName);
		return result;
	}
    // 跳转指针
	JNIEXPORT jlong JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_jump(JNIEnv* env, jclass clazz, jlong addr,jint count) {
		return jump(addr,count);
	}
	// 跳转指针 [32位]
	JNIEXPORT jlong JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_jump32(JNIEnv* env, jclass clazz, jlong addr) {
		return jump32(addr);
	}
	// 跳转指针 [64位]
	JNIEXPORT jlong JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_jump64(JNIEnv* env, jclass clazz, jlong addr) {
		return jump64(addr);
	}
	// 设置指定内存地址指向的值 🛡️该方法已对当前进程进行保护 防止GG模糊🛡️
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_setMemoryAddrValue(JNIEnv* env, jclass clazz, jstring value, jlong addr, jint type, jboolean isFree) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		int result = setMemoryAddrValue(nativeValue, addr, type, isFree);
		env->ReleaseStringUTFChars(value, nativeValue);
		return result;
	}
	// 获取指定内存地址的数据
	JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getMemoryAddrData(JNIEnv* env, jclass clazz, jlong addr, jint type) {
		char* result = getMemoryAddrData(addr, type);
		jstring javaString = env->NewStringUTF(result);
		return javaString;
	}

    JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getDword(JNIEnv *env, jclass clazz, jlong addr) {
        return getDword(static_cast<unsigned long>(addr));
    }
    JNIEXPORT jfloat JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getFloat(JNIEnv *env, jclass clazz, jlong addr) {
        return getFloat(static_cast<unsigned long>(addr));
    }
    JNIEXPORT jdouble JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getDouble(JNIEnv *env, jclass clazz, jlong addr) {
        return getDouble(static_cast<unsigned long>(addr));
    }
    JNIEXPORT jlong JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getQword(JNIEnv *env, jclass clazz, jlong addr) {
        return getQword(static_cast<unsigned long>(addr));
    }
    JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getWord(JNIEnv *env, jclass clazz, jlong addr) {
        return getWord(static_cast<unsigned long>(addr));
    }
    JNIEXPORT jbyte JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getByte(JNIEnv *env, jclass clazz, jlong addr) {
        return getByte(static_cast<unsigned long>(addr));
    }
    JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getString(JNIEnv *env, jclass clazz, jlong addr) {
        char* str = getString(static_cast<unsigned long>(addr));
        return env->NewStringUTF(str);
    }
    JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getDword_1t(JNIEnv *env, jclass clazz, jlong addr) {
        return getDword_t(static_cast<unsigned long>(addr));  
    }
    JNIEXPORT jfloat JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getFloat_1t(JNIEnv *env, jclass clazz, jlong addr) {
        return getFloat_t(static_cast<unsigned long>(addr));  
    }
    JNIEXPORT jdouble JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getDouble_1t(JNIEnv *env, jclass clazz, jlong addr) {
        return getDouble_t(static_cast<unsigned long>(addr));  
    }
    JNIEXPORT jlong JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getQword_1t(JNIEnv *env, jclass clazz, jlong addr) {
        return getQword_t(static_cast<unsigned long>(addr)); 
    }
    JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getWord_1t(JNIEnv *env, jclass clazz, jlong addr) {
        return getWord_t(static_cast<unsigned long>(addr));  
    }
    JNIEXPORT jbyte JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getByte_1t(JNIEnv *env, jclass clazz, jlong addr) {
        return getByte_t(static_cast<unsigned long>(addr)); 
    }
    JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getString_1t(JNIEnv *env, jclass clazz, jlong startAddr) {
        char* str = getString_t(static_cast<unsigned long>(startAddr));  
        return env->NewStringUTF(str);  
    }
    // 设置要搜索的内存区域
    JNIEXPORT void JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_setMemoryArea(JNIEnv* env, jclass clazz, jint memoryArea) {
      LOGI("setMemoryArea");
      setMemoryArea(memoryArea);
    }

    // 内存搜索
    JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_MemorySearch
    (JNIEnv* env, jclass clazz, jstring value, jint type) {
            const char* nativeValue = env->GetStringUTFChars(value, nullptr);
            LOGI("MemorySearch:nativeValue=%s,type=%d",nativeValue,type);
            std::vector<unsigned long> results = MemorySearch(nativeValue, type);
            LOGI("memsearch result:%d",results.size());
            env->ReleaseStringUTFChars(value, nativeValue);
            jlongArray resultArray = env->NewLongArray(results.size());
            auto* arrayElements = new jlong[results.size()];
            for (size_t i = 0; i < results.size(); ++i) {
                    arrayElements[i] = static_cast<jlong>(results[i]);
            }
            env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
            delete[] arrayElements;
            return resultArray;
    }
	// 内存搜索范围值
	JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_MemorySearchRange
	(JNIEnv* env, jclass clazz, jstring value, jint type) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		std::vector<unsigned long> results = MemorySearchRange(nativeValue, type);
		env->ReleaseStringUTFChars(value, nativeValue);

		jlongArray resultArray = env->NewLongArray(results.size());
		jlong* arrayElements = new jlong[results.size()];
		for (size_t i = 0; i < results.size(); ++i) {
			arrayElements[i] = static_cast<jlong>(results[i]);
		}
		env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
		delete[] arrayElements;
		return resultArray;
	}
	// 联合内存搜索
	JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_MemorySearchUnited
	(JNIEnv* env, jclass clazz, jstring value, jint type) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		std::vector<unsigned long> results = MemorySearchUnited(nativeValue, type);
		env->ReleaseStringUTFChars(value, nativeValue);

		jlongArray resultArray = env->NewLongArray(results.size());
		jlong* arrayElements = new jlong[results.size()];
		for (size_t i = 0; i < results.size(); ++i) {
			arrayElements[i] = static_cast<jlong>(results[i]);
		}
		env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
		delete[] arrayElements;
		return resultArray;
	}
	// 偏移改善结果
	JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_ImproveOffset
	(JNIEnv* env, jclass clazz, jstring value, jint type, jlong offset) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		std::vector<unsigned long> results = ImproveOffset(nativeValue, type, static_cast<unsigned long>(offset));
		env->ReleaseStringUTFChars(value, nativeValue);

		jlongArray resultArray = env->NewLongArray(results.size());
		jlong* arrayElements = new jlong[results.size()];
		for (size_t i = 0; i < results.size(); ++i) {
			arrayElements[i] = static_cast<jlong>(results[i]);
		}
		env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
		delete[] arrayElements;
		return resultArray;
	}
	// 偏移范围改善结果
	JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_ImproveOffsetRange
	(JNIEnv* env, jclass clazz, jstring value, jint type, jlong offset) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		std::vector<unsigned long> results = ImproveOffsetRange(nativeValue, type, static_cast<unsigned long>(offset));
		env->ReleaseStringUTFChars(value, nativeValue);

		jlongArray resultArray = env->NewLongArray(results.size());
		jlong* arrayElements = new jlong[results.size()];
		for (size_t i = 0; i < results.size(); ++i) {
			arrayElements[i] = static_cast<jlong>(results[i]);
		}
		env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
		delete[] arrayElements;
		return resultArray;
	}
	// 偏移联合改善结果
	JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_ImproveOffsetUnited
	(JNIEnv* env, jclass clazz, jstring value, jint type, jlong offset) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		std::vector<unsigned long> results = ImproveOffsetUnited(nativeValue, type, static_cast<unsigned long>(offset));
		env->ReleaseStringUTFChars(value, nativeValue);

		jlongArray resultArray = env->NewLongArray(results.size());
		jlong* arrayElements = new jlong[results.size()];
		for (size_t i = 0; i < results.size(); ++i) {
			arrayElements[i] = static_cast<jlong>(results[i]);
		}
		env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
		delete[] arrayElements;
		return resultArray;
	}
	// 直接改善结果
	JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_ImproveValue
	(JNIEnv* env, jclass clazz, jstring value, jint type) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		std::vector<unsigned long> results = ImproveValue(nativeValue, type);
		env->ReleaseStringUTFChars(value, nativeValue);
		jlongArray resultArray = env->NewLongArray(results.size());
		jlong* arrayElements = new jlong[results.size()];
		for (size_t i = 0; i < results.size(); ++i) {
			arrayElements[i] = static_cast<jlong>(results[i]);
		}
		env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
		delete[] arrayElements;
		return resultArray;
	}
	// 结果偏移写入数据
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_MemoryOffsetWrite
	(JNIEnv* env, jclass clazz, jstring value, jint type, jlong offset, jboolean isFree) {
		const char* nativeValue = env->GetStringUTFChars(value, nullptr);
		int result = MemoryOffsetWrite(nativeValue, type, static_cast<unsigned long>(offset), isFree);
		env->ReleaseStringUTFChars(value, nativeValue);
		return result;
	}
	// 获取最终搜索结果数量
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getResultCount
	(JNIEnv* env, jclass clazz) {
		return getResultCount();
	}
	// 获取最终搜索结果列表
	JNIEXPORT jlongArray JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getResultList
	(JNIEnv* env, jclass clazz) {
		std::vector<unsigned long> results = getResultList();
		jlongArray resultArray = env->NewLongArray(results.size());
		jlong* arrayElements = new jlong[results.size()];
		for (size_t i = 0; i < results.size(); ++i) {
			arrayElements[i] = static_cast<jlong>(results[i]);
		}
		env->SetLongArrayRegion(resultArray, 0, results.size(), arrayElements);
		delete[] arrayElements;
		return resultArray;
	}
	// 打印最终搜索结果列表到指定文件
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_printResultListToFile
	(JNIEnv* env, jclass clazz, jstring filePath) {
		const char* nativeFilePath = env->GetStringUTFChars(filePath, 0);
		int result = printResultListToFile(nativeFilePath);
		env->ReleaseStringUTFChars(filePath, nativeFilePath);
		return result;
	}
	// 清空最终搜索结果列表
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_clearResultList
	(JNIEnv* env, jclass clazz) {
		return clearResultList();
	}
	// 设置冻结修改延迟
	JNIEXPORT void JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_setFreezeDelayMs(JNIEnv* env, jclass clazz, jint delay) {
		setFreezeDelayMs(static_cast<uint32_t>(delay));
	}
	// 获取冻结修改项目数量
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getFreezeNum(JNIEnv* env, jclass clazz) {
		return static_cast<jint>(getFreezeNum());
	}
	// 添加一个冻结修改项目
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_addFreezeItem(JNIEnv* env, jclass clazz, jstring value, jlong addr, jint type) {
		const char* nativeValue = env->GetStringUTFChars(value, 0);
		int result = addFreezeItem(nativeValue, static_cast<unsigned long>(addr), static_cast<int>(type));
		env->ReleaseStringUTFChars(value, nativeValue);
		return static_cast<jint>(result);
	}
	// 移除一个冻结修改项目
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_removeFreezeItem(JNIEnv* env, jclass clazz, jlong addr) {
		return static_cast<jint>(removeFreezeItem(static_cast<unsigned long>(addr)));
	}
	// 移除所有冻结修改项目
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_removeAllFreezeItem(JNIEnv* env, jclass clazz) {
		return static_cast<jint>(removeAllFreezeItem());
	}
	// 冻结循环修改线程忽略$
	// 
	// 开始冻结所有修改项目
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_startAllFreeze(JNIEnv* env, jclass clazz) {
		return static_cast<jint>(startAllFreeze());
	}
	// 停止冻结所有修改项目
	JNIEXPORT jint JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_stopAllFreeze(JNIEnv* env, jclass clazz) {
		return static_cast<jint>(stopAllFreeze());
	}



	// 获取指定内存地址的Maps映射行
	JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getMemoryAddrMapLine
	(JNIEnv* env, jclass clazz, jlong address) {
		char* result = getMemoryAddrMapLine(static_cast<unsigned long>(address));
		jstring jResult = env->NewStringUTF(result);
		return jResult;
	}
	// 获取Maps映射行所在内存区域名称
	JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getMapLineMemoryAreaName
	(JNIEnv* env, jclass clazz, jstring mapLine) {
		const char* nativeMapLine = env->GetStringUTFChars(mapLine, 0);
		char* result = getMapLineMemoryAreaName(nativeMapLine);
		jstring jResult = env->NewStringUTF(result);
		env->ReleaseStringUTFChars(mapLine, nativeMapLine);
		return jResult;
	}
	// 获取指定内存id的内存名称
	JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getMemoryAreaIdName
	(JNIEnv* env, jclass clazz, jint memid) {
		char* result = getMemoryAreaIdName(static_cast<int>(memid));
		jstring jResult = env->NewStringUTF(result);
		return jResult;
	}
	// 获取当前内存名称
	JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getMemoryAreaName
	(JNIEnv* env, jclass clazz) {
		char* result = getMemoryAreaName();
		jstring jResult = env->NewStringUTF(result);
		return jResult;
	}
	// 获取指定数据类型id的数据类型名称
	JNIEXPORT jstring JNICALL Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_getDataTypeName
	(JNIEnv* env, jclass clazz, jint typeId) {
		char* result = getDataTypeName(static_cast<int>(typeId));
		jstring jResult = env->NewStringUTF(result);
		return jResult;
	}


JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env;
    if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    LOGI("Algui动态共享库加载完毕");
    return JNI_VERSION_1_6;
}

JNIEXPORT jstring JNICALL
Java_com_bytecat_algui_AlguiHacker_AlguiNativeMemTool_test(JNIEnv *env, jclass clazz) {
    pid_t mypid = getpid();
    std::string msg = "这是来自jni的返回，程序pid：" + to_string(mypid)+"设置的pid："+ to_string(pid)+" getResultCount:"+ to_string(getResultCount());

    int fd = open("/proc/self/mem", O_RDWR);
    if (fd < 0) {
      __android_log_print(ANDROID_LOG_ERROR, "inject", "open failed errno=%d %s", errno, strerror(errno));
    } else {
      char buf[16];
      ssize_t n = pread(fd, buf, sizeof(buf), (off_t)0x1000);
      __android_log_print(ANDROID_LOG_ERROR, "inject", "pread ret=%zd errno=%d %s", n, errno, strerror(errno));
      close(fd);
    }
    return env->NewStringUTF(msg.c_str());
}

}

